import stringify from 'qs/lib/stringify';
import api from '../api';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import { message, Modal } from 'antd';
import _ from 'lodash';
import LeaderLine from './thirdPackage/leader-line.min';
import commonText from './commonText';
import configType from './config';
import uuid from 'es6-uuid';
import { divide, times } from 'number-precision';
import * as XLSX from 'xlsx/xlsx';

/**
 * 比较数组是否完全一样的函数
 * @param arr1
 * @param arr2
 * @param compareKey 比较的key
 * @returns {{unmatchedDataArr1: *[], unmatchedDataArr2: *[]}} 返回找到的相互不存在的数据
 */
export function compareArrays(arr1, arr2, compareKey) {
  const unmatchedDataArr1 = [];
  const unmatchedDataArr2 = [];
  // 比较第一个数组的每个对象是否在第二个数组中存在
  for (const obj1 of arr1) {
    const foundMatch = arr2.some((obj2) => obj2[compareKey] === obj1[compareKey]);
    if (!foundMatch) {
      unmatchedDataArr1.push(obj1);
    }
  }
  // 比较第二个数组的每个对象是否在第一个数组中存在
  for (const obj2 of arr2) {
    const foundMatch = arr1.some((obj1) => obj1[compareKey] === obj2[compareKey]);
    if (!foundMatch) {
      unmatchedDataArr2.push(obj2);
    }
  }
  return { unmatchedDataArr1, unmatchedDataArr2 };
}
// 修改对象的key
function transKey(data, keyMap) {
  if (Object.keys(data).length === 0) return data;
  return Object.keys(data).reduce((newData, key) => {
    const newKey = keyMap[key] || key;
    newData[newKey] = data[key];
    return newData;
  }, {});
}
/**
 * 解析excel
 * @param {File} fileStream 文件对象
 * @param {Array} keyMaps 键值对替换数组，有几个sheet数组长度就是几 [{ '名称': name1 }, { '名称': name2 }]
 * @returns {Promise<object>} 返回Promise对象， resolve的结果为 { sheetName1: data1, sheetName2: data2 }
 */
export const parseExcelFile = (fileStream, keyMaps = []) => {
  const reader = new FileReader();
  return new Promise((resolve, reject) => {
    reader.onload = (event) => {
      try {
        const { result } = event.target;
        const workbook = XLSX.read(result, { type: 'binary' }); // 读取文件
        const resData = [];
        let index = 0;
        // 循环文件中的每个表
        for (const sheet in workbook.Sheets) {
          if (workbook.Sheets.hasOwnProperty(sheet)) {
            const dataSource = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
            resData.push({
              sheetName: sheet,
              dataSource:
                keyMaps.length > 0
                  ? dataSource.map((ele) => {
                      return transKey(ele, keyMaps[index]); // 替换key，sheet_to_json返回的是中文表头名
                    })
                  : dataSource,
            });
            index++;
          }
        }
        resolve(resData);
      } catch (e) {
        reject(e);
        message.error('文件类型不正确！');
      }
    };
    reader.readAsBinaryString(fileStream);
  });
};

/**
 * 精确四舍五入
 * @param { number } value 值
 * @param { number } bit 保留位数默认2
 * @returns {string}
 */
export function reservedBits(value, bit = 2) {
  return divide(Math.round(times(value ?? 0, 100)), 100).toFixed(bit);
}
/**
 * 根据返回的data获取echarts的数据
 * @param {object} obj
 * @param {string} obj.type
 * @param {object[]} obj.data
 * @param {obj[]} dataSource
 * @example
 * @param {object} returnValue
 * @returns {*[][]|(*[]|string[])[]}
 */
export function conversionChartsData(dataSource) {
  if (dataSource.length === 0) return [[], []];
  const seriesData = [];
  const xAxisData = dataSource[0].data.length === 0 ? [] : Object.keys(dataSource[0].data[0]);
  dataSource.map((ele) => {
    const obj = {};
    obj.data = ele.data.length === 0 ? [] : Object.values(ele.data[0]);
    obj.name = ele.type;
    seriesData.push(obj);
  });
  return [xAxisData, seriesData];
}
/** 计算设置tab宽度 */
export function tabDiyWidth() {
  /** 获取窗口的宽度 */
  const { clientWidth } = document.body;
  /** tab的宽度=窗口的宽度-logo(220)-右边的提示（700） */
  const tabWidth = clientWidth - 220 - 700;
  /** 设置tab的宽度 */
  if (document.getElementById('tabDiyWidth')) {
    document.getElementById('tabDiyWidth').firstChild.getElementsByTagName('div')[0].style.width = `${tabWidth}px`;
  }
}

// 退出登录 需要重订向路由
export function redierctLogin() {
  const urlParams = new URL(window.location.href); // 设置重定向
  const pathname = urlParams.hash ? urlParams.hash.split('#')[1] : '';
  if (pathname == '/login') return; // 登录页面不可重定向
  // add the parameters in the url
  urlParams.searchParams.set('redirect', pathname);
  window.history.replaceState(null, 'login', urlParams.href); // 定位到登录页面
}

// 返回当前登录用户的身份信息
export function getUserInfo() {
  const superMan = localStorage.getItem('antd-pro-superMan');
  if (superMan == 'true') {
    return { isSuper: true };
  } else {
    const tenantAdmin = localStorage.getItem('antd-pro-admin') == 'true';
    const tenantName = localStorage.getItem('antd-pro-tenant');
    const tenantCHNname = localStorage.getItem('antd-pro-tenantName');
    const isOperationsManage = localStorage.getItem('isOperationsManage') == 'true';
    return {
      isSuper: false, // 是否是超级管理员 布尔值
      isTenantAdmin: tenantAdmin, // 是否是租户管理员 布尔值
      tenantName, // 属于哪个租户
      tenantCHNname, // 租户中文名称
      isOperationsManage, // 是否有运营管理角色 布尔值
    };
  }
}

// 后台下指令唯一标识符
export async function uniqueKey(type) {
  const res = type == 'new' ? await api.getuniqueKeyNew({}) : await api.getuniqueKey({});
  if (res && res.code == 0) {
    return res.data.id || res.data;
  }
}

// 导出
/**
 * @param {string} url 导出地址
 * @param {object} query 参数
 * @param {boolean} isMore 是否都文件导出
 */
export async function exportFile(url, query = {}, isMore) {
  if (!url) return;

  // 互联网架构改造任务:
  // 需求：1、接口前缀统一调整；2、请求头增加hToken
  // 调整：
  // 1、上传接口因为在各自文件中传入接口地址，文件较多，所以在此公共方法对接口前缀统一调整。
  // 2、接口增加htoken，不需要先走api.getExportId接口获取ivUser，直接调用url下载接口
  // 3、原方法location.href 跳转请求头无法增加hToken，用fetch处理--需要获取响应头过去文件名称，然后通过a标签跳转
  let value;
  if (url.match('^api/v1/')) {
    value = configType.interfaces.type1 + url.replace('api/v1/', '');
  } else if (url.match('^api/v3/')) {
    value = configType.interfaces.type2 + url.replace('api/v3/', '');
  } else if (url.match('^thfx/')) {
    value = configType.interfaces.type3 + url.replace('thfx/', '');
  } else if (url.match('^api/python/evar/api/')) {
    value = configType.interfaces.type6 + url.replace('api/python/evar/api/', '');
  } else if (url.match('^api/evar/api/')) {
    value = configType.interfaces.type7 + url.replace('api/evar/api/', '');
  } else {
    value = url;
  }
  if (isMore) {
    // 执行批量下载
    query.map((item) => {
      const querys = { uniquekey: item.value };
      let fileName;
      fetch(`${value}?${stringify(querys)}`, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          hToken: localStorage.getItem('antd-pro-token'),
        },
        responseType: 'blob', // blob获取二进制流
      })
        .then((response) => {
          // 获取响应头过去文件名称
          const fileNameEncode = response.headers.get('content-disposition')?.split('filename=')[1];
          // 解码
          fileName = decodeURIComponent(fileNameEncode);
          console.log('fileName', fileName);
          return response.blob();
        })
        .then((res) => {
          const a = document.createElement('a');
          const body = document.querySelector('body');
          const bl = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
          a.download = fileName;
          a.href = window.URL.createObjectURL(bl);
          a.style.display = 'none';
          body.appendChild(a);
          a.click();
          body.removeChild(a);
          window.URL.revokeObjectURL(a.href);
        });
    });
  } else {
    let fileName;
    fetch(`${value}?${stringify(query)}`, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        hToken: localStorage.getItem('antd-pro-token'),
      },
      responseType: 'blob', // blob获取二进制流
    })
      .then((response) => {
        // 获取响应头过去文件名称
        const fileNameEncode = response.headers.get('content-disposition')?.split('filename=')[1];
        // 解码
        fileName = decodeURIComponent(fileNameEncode);
        console.log('fileName', fileName);
        return response.blob();
      })
      .then((res) => {
        const a = document.createElement('a');
        const body = document.querySelector('body');
        const bl = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
        a.download = fileName;
        a.href = window.URL.createObjectURL(bl);
        a.style.display = 'none';
        body.appendChild(a);
        a.click();
        body.removeChild(a);
        window.URL.revokeObjectURL(a.href);
      });
  }
}

// dom元素连接，绘制引导线
/**
 * 连接两个dom接口
 * @param {element} start 开始dom
 * @param {element} end 结束dom
 * @param {object} options 配置
 */
export function lineConnect(start, end, options = {}) {
  const newOptions = {
    color: '#AABDF4', // 指引线颜色
    dash: {
      len: 4,
      gap: 2,
      animation: true,
    },
    hide: true, // 绘制时隐藏，默认为false，在初始化时可能会出现闪烁的线条
    size: 2, // 线条尺寸
    path: 'fluid',
    startSocket: 'left', // 在指引线开始的地方从元素左侧开始
    endSocket: 'right', // 在指引线开始的地方从元素右侧结束
    endPlug: 'disc', // 指引线结束点的样式
    ...options,
  };
  const styles = {
    paddingTop: null,
    paddingRight: null,
    paddingBottom: null,
    paddingLeft: null,
    cursor: null,
    backgroundColor: null,
    backgroundImage: null,
    backgroundSize: null,
    backgroundPosition: null,
    backgroundRepeat: null,
  };
  const leaderLine = new LeaderLine(
    LeaderLine.mouseHoverAnchor({
      element: start,
      showEffectName: 'draw',
      animOptions: {
        // 指引线动效
        duration: 500,
      },
      style: styles,
      hoverStyle: styles,
    }),
    end,
    newOptions,
  );
  leaderLine.show();
  return leaderLine;
}

// 在用户手动退出和系统超时被迫退出两处，使用window.localStorage.clear()，window.sessionStorage.clear()删除
export function clearStorage() {
  console.log('退出清空缓存');
  // 被迫登出 弹窗显示多个 处理为一个弹窗标志位 保留
  let flag;
  if (sessionStorage.getItem('prevent')) {
    flag = true;
  }
  window.localStorage.clear();
  window.sessionStorage.clear();
  if (flag) {
    sessionStorage.setItem('prevent', 1);
  }
}

// 判断租户是否配置自动交收，若配置自动交收给予弹窗提醒
/**
 * @param {number} type 1-指令下达自动交收提示文本,2-簿记下达自动交收提示文本
 * @param {element} url 指令下达接口
 * @param {object} params 接口入参
 * @param {Function} dispatch
 * @param {Function} callback
 *
 */
export function AutomaticSettlement(type, url, params, dispatch, callback) {
  if (localStorage.getItem('unsecuredAutomaticSettlement') == 1) {
    Modal.confirm({
      title: type == 1 ? commonText.tradeText : commonText.bookKeepingText,
      cancelText: '取消',
      okText: '确定',
      icon: <ExclamationCircleOutlined />,
      onOk() {
        // 判断dispatch 有无 ，无 则不发出请求；有发出
        if (dispatch)
          dispatch({
            type: url,
            payload: params,
            callback,
          });
        else {
          callback();
        }
      },
    });
    return true;
  }
}

// 判断当前登录用户是否是测试专用(公共)角色 code==> jssx
export function isTestRole() {
  if (!localStorage.getItem('roleIds')) return;
  const roleIds = JSON.parse(decodeURI(localStorage.getItem('roleIds')));
  return roleIds.includes('jssx');
}
// 判断当前登录用户是否包含某个角色
export function isIncluesRole(roleId) {
  if (!localStorage.getItem('roleIds')) return;
  const roleIds = JSON.parse(decodeURI(localStorage.getItem('roleIds')));
  return roleIds.includes(roleId);
}

// echart图数据格式转表格数据
export function echartsToTable(data, columns) {
  if (!data.xAxis) return;
  const dataSource = [];
  data?.xAxis.map((item) => {
    const obj = {
      [columns[0].key]: item,
      id: uuid(10),
    };
    dataSource.push(obj);
  });
  dataSource.map((item, index) => {
    data?.series.map((seriesItem) => {
      columns.map((columnsItem) => {
        if (seriesItem.name == columnsItem.title) {
          item[columnsItem.key] = seriesItem.data[index];
        }
      });
    });
  });
  return dataSource;
}

/**
 * 转换交易方向为文字
 * @param type {string}
 * @param directionId {string}
 * @param dicMap {React.ReactPropTypes.object} 枚举对象
 * @returns {string} directionName
 */
export function convertDirection(type, directionId, dicMap) {
  let key = type === '4' ? 'BUY_BACK_DIR' : 'JYS_ORDER_SIDE';
  if (type === '5') key = 'fund_Trade_Order_apply_type';
  if (type === '6') key = 'FINA_FLOCKING_DIR';
  if (type === '7') key = 'ORDERSIDE_DICT';
  if (type === '9') {
    if (directionId == '1') {
      return '买';
    }
    if (directionId == '2') {
      return '卖';
    }
  }
  const values = dicMap[key] || [];
  let text = '';
  values.forEach((item) => {
    if (item.code === directionId) text = item.value;
  });
  return text;
}
/**
 *
 * @param fn {Function} 函数 必传
 * @param data {*} 函数参数 非必传
 * @param event {*} 事件 非必传
 * @param wait {number} 防抖时间 非必传
 * @returns {ReturnType<function(): *>}
 */
export const debounceFn = _.debounce((fn, data, event) => fn(data, event), 500);
// 页面首次打开，根据路由得到对应的选中 和展开的菜单集合
// userinfo/2144/id => ['/userinfo','/useinfo/2144,'/userindo/2144/id']
export function urlToList(url) {
  const urllist = url.split('/').filter((i) => i);
  return urllist.map((urlItem, index) => {
    return `/${urllist.slice(0, index + 1).join('/')}`;
  });
}

// 获取cookies
export function setCookie(name, value) {
  const Days = 1; // 有效时间
  const exp = new Date();
  exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
  document.cookie = `${name}=${escape(value)};expires=${exp.toGMTString()}`;
}
export function getCookie(name) {
  const prefix = `${name}=`;
  const start = document.cookie.indexOf(prefix);
  if (start == -1) {
    return null;
  }
  let end = document.cookie.indexOf(';', start + prefix.length);
  if (end == -1) {
    end = document.cookie.length;
  }
  const value = document.cookie.substring(start + prefix.length, end);
  return unescape(value);
}
// 清空cookie
export function clearCookie() {
  const keys = document.cookie.match(/[^ =;]+(?=\=)/g);
  console.log(keys);
  if (keys) {
    for (let i = keys.length; i--; ) {
      document.cookie = `${keys[i]}=0;path=/;expires=${new Date(0).toUTCString()}`; // 清除当前域名下的,例如：http://168.64.10.191:9106/
      document.cookie = `${keys[i]}=0;path=/maat;domain=${document.domain};expires=${new Date(0).toUTCString()}`; // 清除当前域名下的，例如 http://168.64.10.191:9106/
    }
  }
  console.log('已清除');
}
/**
 *将后端返回的图表结构转换成echarts组件需要的格式
 * @param data {array} 数组参数必传
 * @param type {string} 非必填 暂支持 line bar格式 *
 * @returns {object} 对象包含 echarts组件需要的两个值,
 * {
    xAxis:[],
    series:[]
  }
 */
export function formatChartsDataFn(data = [], type) {
  const obj = {
    xAxis: [],
    series: [],
  };
  if (data.length) {
    if (data[0]?.data?.length) {
      // 拿到xAxis
      obj.xAxis = data[0]?.data?.map((item) => Object.keys(item)[0]);
    }
    // 获取series
    data.map((item) => {
      const row = {
        name: item.type,
        data: item?.data?.length ? item.data.map((item) => Object.values(item)[0]) : [],
      };
      if (type) row.type = type; // 设置展示类型 柱状图 还是折线图
      obj.series.push(row);
    });
  }
  return obj;
}

/* 待删除 */

// 判断当前环境是不是资管，若是资管，返回登录用户及其他条件，若不是资管，返回false
export function isZiGuanEvir() {
  // 若是资管，window.location.hash值为#/maat/securityMnt/couponPoolQuery/bond?iv-user=006562
  const location = window.location.href;
  // let location = 'http://168.63.65.193:8089/#/maat/securityMnt/couponPoolQuery/bond?iv-user=006562&pondID=111111';
  const search = location.split('?');
  if (search && search.length == 2) {
    const items = search[1].split('&');
    const args = {};
    items &&
      items.forEach((item) => {
        const obj = item.split('=');
        args[obj[0]] = obj[1];
      });

    // 查询条件中包含iv-user的证明是资管
    if (args['iv-user']) {
      return args;
    }
  }
  return false;
}

// 计算费用函数 // 费用计算逻辑未完全梳理清楚，后续用户有真正需求时再添加费用计算相关逻辑
export async function calculateFee(data, flag) {
  if (!flag) return;
  for (const i in data) {
    if (data[i] == undefined) return undefined;
  }
  const res = await api.getCalculateFee(data);
  if (res && res.code == 0) {
    return res.data?.dataSource;
  } else {
    message.error(res?.msg || '费用计算失败');
    return undefined;
  }
}
